package com.starlink.common.strategy.vip;

import com.starlink.common.enums.OrderTypeEnum;
import com.starlink.common.strategy.IPayNotify;
import com.starlink.model.domain.UserDO;
import com.starlink.model.domain.UserVipPaymentDO;
import com.starlink.model.domain.UserVipSetDO;
import com.starlink.model.request.UserVipPaymentRequest;
import com.starlink.model.request.mall.WechatPay;
import com.starlink.model.request.mall.WechatRefund;
import com.starlink.service.UserService;
import com.starlink.service.UserVipPaymentService;
import com.starlink.service.UserVipSetService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

import static com.starlink.common.enums.BooleanEnum.TRUE;

/**
 * @Auther: zhouyuhang01
 * @Date: 2024/5/9 09:23
 * @Description: VipNotifyImpl
 * @Version 1.0.0
 */
@Component
public class VipNotifyImpl implements IPayNotify {
    @Autowired
    private UserService userService;
    @Autowired
    private UserVipPaymentService paymentService;
    @Autowired
    private UserVipSetService userVipSetService;
    @Override
    public boolean supports(Integer orderType) {
        return OrderTypeEnum.OPEN_VIP.getType().equals(orderType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handle(WechatPay wechatPay) {
        UserVipSetDO one = userVipSetService.lambdaQuery().last("limit 1").one();
        Date vipExpireDate = null;
        if (ObjectUtils.isEmpty(one)){
            vipExpireDate = calculateExpirationDate(1);
        }else {
            Integer timeLimit = one.getTimeLimit();
            if (timeLimit==1){
                vipExpireDate = calculateExpirationDate(99);
            }
            if (timeLimit==2){
                vipExpireDate = calculateExpirationDate(one.getNumberOfYears());
            }
        }
        //修改用户vip状态
        AtomicInteger atomicInteger = new AtomicInteger(1);
        Long userId = wechatPay.getUserId();
        String orderNum = wechatPay.getOrderNum();
        String weChatOrderId = wechatPay.getWeChatOrderId();
        String amount = wechatPay.getAmount();
        UserDO userDO = userService.lambdaQuery()
                .eq(UserDO::getId, userId)
                .one();
        Integer vip = userDO.getVip();
        if (vip != null) {
            if (userDO.getVip() == TRUE.getCode()) {
                Date expireDate = userDO.getVipExpireDate();
                if (ObjectUtils.isEmpty(one)) {
                    vipExpireDate = calculateOldVipExpirationDate(expireDate, 1);
                } else {
                    Integer timeLimit = one.getTimeLimit();
                    if (timeLimit == 1) {
                        atomicInteger.set(0);
                        vipExpireDate = calculateOldVipExpirationDate(expireDate, 99);
                    }
                    if (timeLimit == 2) {
                        vipExpireDate = calculateOldVipExpirationDate(expireDate, one.getNumberOfYears());
                    }
                }
            }
        }
        userService.lambdaUpdate()
                .set(UserDO::getVip,TRUE.getCode())
                .set(UserDO::getVipExpireDate,vipExpireDate)
                .set(UserDO::getSupportRenewal,atomicInteger.get())
                .eq(UserDO::getId,userId)
                .update();
        //新增支付记录
        UserVipPaymentDO vipPaymentDO = paymentService.lambdaQuery().eq(UserVipPaymentDO::getWxOrderNum, weChatOrderId).last("limit 1").one();
        if (ObjectUtils.isEmpty(vipPaymentDO)) {
            UserVipPaymentRequest paymentRequest = new UserVipPaymentRequest();
            paymentRequest.setAmount(new BigDecimal(amount));
            paymentRequest.setOrderNum(orderNum);
            paymentRequest.setWxOrderNum(weChatOrderId);
            paymentRequest.setCreateTime(new Date());
            paymentRequest.setCreateUser(userId);
            paymentService.add(paymentRequest);
        }
    }

    @Override
    public void refundHandle(WechatRefund wechatPay) {

    }

    /**
     * 新开会员时间计算
     * @param year
     * @return
     */
    public static Date calculateExpirationDate(Integer year) {
        // 获取当前时间
        Date currentDate = new Date();

        // 创建日历对象，并设置为当前时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);

        // 将日历对象的年份加上year年
        calendar.add(Calendar.YEAR, year);

        // 设置时分秒与当前时间一致
        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE));
        calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND));
        calendar.set(Calendar.MILLISECOND, calendar.get(Calendar.MILLISECOND));

        // 获取新的日期对象，即为当前时间加上year年，时分秒与当前时间一致
        Date expirationDate = calendar.getTime();

        return expirationDate;
    }

    /**
     * 续费会员时间计算
     * @param year
     * @return
     */
    public static Date calculateOldVipExpirationDate(Date currentDate,Integer year) {
        // 创建日历对象，并设置为会员到期的时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);

        // 将日历对象的年份加上year年
        calendar.add(Calendar.YEAR, year);

        // 设置时分秒与当前时间一致
        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE));
        calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND));
        calendar.set(Calendar.MILLISECOND, calendar.get(Calendar.MILLISECOND));

        // 获取新的日期对象，即为当前时间加上year年，时分秒与当前时间一致
        Date expirationDate = calendar.getTime();

        return expirationDate;
    }
}
